using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Game;
using NetProtocol.POD;

namespace IQIGame.Onigao.GamePlay
{
    public class LevelPlayRegionController : TModuleController
    {
        public LevelPlayController levelPlayCtrl => parent as LevelPlayController;

        #region sub controller

        public LevelPlaySceneCtrl sceneCtrl { get; private set; }
        public LevelPlayEntityCtrl entityCtrl { get; private set; }
        public LevelPlayDisplayObjCtrl displayObjCtrl { get; private set; }
        public LevelPlayEntityViewCtrl entityViewCtrl { get; private set; }
        public LevelPlayCharacterCtrl interactCtrl { get; private set; }
        public LevelPlayCameraCtrl cameraCtrl { get; private set; }
        public LevelPlayNavigationCtrl navigationCtrl { get; private set; }
        public LevelPlayAreaEffectCtrl areaEffectCtrl { get; private set; }
        public LevelPlayMediaCtrl mediaCtrl { get; private set; }
        public LevelPlayMiniGameCtrl miniGameCtrl { get; private set; }
        public LevelPlayEffectCtrl effectCtrl { get; private set; }
        public LevelPlayElevatorFenceCtrl elevatorFenceCtrl { get; private set; }

        #endregion

        public UILevelMain uilevelMain { get; private set; }
        public UILevelInput uilevelInput { get; private set; }
        public UILightDialog uilevelLightDialog { get; private set; }
        public LevelRegionPackConfig cfgRegionPack { get; private set; }
        public DynLevelRegion levelRegion { get; private set; }
        public bool isSceneReady { get; private set; }

        public LevelPlayRegionController()
        {
            CreateSubCtrls();
        }

        protected override void OnModuleGameplayInit()
        {
            AddListeners();
        }

        protected override void OnSceneLoaded()
        {
        }

        protected virtual void CreateSubCtrls()
        {
            interactCtrl = AddSubController<LevelPlayCharacterCtrl>();
            sceneCtrl = AddSubController<LevelPlaySceneCtrl>();
            entityCtrl = AddSubController<LevelPlayEntityCtrl>();
            displayObjCtrl = AddSubController<LevelPlayDisplayObjCtrl>();
            entityViewCtrl = AddSubController<LevelPlayEntityViewCtrl>();
            cameraCtrl = AddSubController<LevelPlayCameraCtrl>();
            navigationCtrl = AddSubController<LevelPlayNavigationCtrl>();
            areaEffectCtrl = AddSubController<LevelPlayAreaEffectCtrl>();
            mediaCtrl = AddSubController<LevelPlayMediaCtrl>();
            miniGameCtrl = AddSubController<LevelPlayMiniGameCtrl>();
            effectCtrl = AddSubController<LevelPlayEffectCtrl>();
            elevatorFenceCtrl = AddSubController<LevelPlayElevatorFenceCtrl>();
        }

        private void AddListeners()
        {
            MsgDispatcher.AddListener<BattleEnterPOD>(MsgEventType.BattleView_Start, OnBattleStart);
            MsgDispatcher.AddListener(MsgEventType.BattleView_Exit, OnBattleExit);
        }

        private void RemoveListeners()
        {
            MsgDispatcher.RemoveListener<BattleEnterPOD>(MsgEventType.BattleView_Start, OnBattleStart);
            MsgDispatcher.RemoveListener(MsgEventType.BattleView_Exit, OnBattleExit);
        }

        public async UniTask EnterRegion(LevelRegionPOD regionPOD)
        {
            int regionCid = regionPOD.cid;
            //初始化地区数据
            cfgRegionPack = await LevelDataUtil.GetGamePlayConfig(regionCid);

            levelRegion = DynLevelRegion.CreateByPOD(regionPOD, cfgRegionPack);

            //模块玩法初始化完毕Controller事件
            DispatchInnerEvent(TControllerEvent.OnModuleGameplayInit);

            // 初始化参数
            this.sceneCtrl.SetInitData();
            // 开始加载场景
            await this.sceneCtrl.FirstEnterScene();
            //场景加载完毕Controller事件
            DispatchInnerEvent(TControllerEvent.OnSceneLoaded);
            isSceneReady = true;
            MsgDispatcher.Broadcast(MsgEventType.GameplayAreaSceneLoaded);
            await ShowDefautUI();
            //通知逻辑层准备好开始了
            var reqTask = await CLevelLogicModule.NetCore.CS_ReadyToStart();
        }

        public async UniTask ShowDefautUI()
        {
            await ManagerCenter.UI.ShowWindowAsync<UILevelMain>();
            await ManagerCenter.UI.ShowWindowAsync<UILevelInput>();
            await ManagerCenter.UI.ShowWindowAsync<UILightDialog>();
            this.uilevelMain = ManagerCenter.UI.GetEntityUI<UILevelMain>();
            this.uilevelInput = ManagerCenter.UI.GetEntityUI<UILevelInput>();
            this.uilevelLightDialog = ManagerCenter.UI.GetEntityUI<UILightDialog>();
            await ManagerCenter.UI.ShowWindowAsync<UIMain>();
            await GameScenePlayUtil.ShowEntityTrack();
            this.interactCtrl.stateOperational.AddJoystickListener();
            uilevelMain.PlayMapNameAnim(cfgRegionPack.cfgRegionInstance.Name);
        }

        public void HideDefautUI()
        {
            ManagerCenter.UI.CloseWindow<UILevelMain>();
            ManagerCenter.UI.CloseWindow<UILevelInput>();
            ManagerCenter.UI.CloseWindow<UILightDialog>();
            uilevelMain = null;
            uilevelInput = null;
            uilevelLightDialog = null;
            ManagerCenter.UI.CloseWindow<UIMain>();
            GameScenePlayUtil.HideQuestTrack();
        }

        /// <summary>
        /// 进入战斗
        /// </summary>
        /// <param name="pod"></param>
        private void OnBattleStart(BattleEnterPOD pod)
        {
            entityViewCtrl.HideTweenView();
            HideDefautUI();
            cameraCtrl.SetCameraActive(false);
            var mainCharacter = entityCtrl.GetMainCharacter();
            mainCharacter.transform.position = GameGlobalConst.FarEnoughPosition;

            sceneCtrl.SetBaseObjActive(false);
        }

        /// <summary>
        /// 战斗结束
        /// 切回关卡相机和显示
        /// </summary>
        private void OnBattleExit()
        {
            InnerOnBattleExit().Forget();
        }

        private async UniTaskVoid InnerOnBattleExit()
        {
            ShowDefautUI().Forget();
            var mainCharacter = entityCtrl.GetMainCharacter();
            mainCharacter.transform.position = mainCharacter.GetUnityVec3Pos();
            var blockController = sceneCtrl.blockController;
            if (blockController != null) //如果不是分块加载的地区，该变量为空
            {
                await blockController.AwaitForLoadingOnUpdate();
            }

            cameraCtrl.SetCameraActive(true);
            sceneCtrl.SetBaseObjActive(true);
        }

        /// <summary>
        /// 团灭处理
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="leaderHeroId"></param>
        /// <returns></returns>
        public void OnTeamWipe(long playerId, long leaderHeroId)
        {
            //英雄播放死亡动画
            foreach (var kv in entityCtrl.heroEntities)
            {
                if (kv.Value.dynLevelHero.id == leaderHeroId)
                {
                    kv.Value.GetAnimationComponent().PlayDie(); //死亡的英雄实体播放死亡动画
                    break;
                }
            }

            //如果是自己的英雄，需要处理额外的逻辑
            var myPlayer = levelPlayCtrl.levelPlayer;
            if (playerId == myPlayer.id)
            {
                //英雄待命，阻止交互指令
                interactCtrl.Standby();
                //弹窗
                UILevelGameOver.ShowAfterCameraEnable().Forget();
            }
        }

        protected override void OnDispose()
        {
            HideDefautUI();
            RemoveListeners();
            interactCtrl = null;
            sceneCtrl = null;
            entityCtrl = null;
            displayObjCtrl = null;
            entityViewCtrl = null;
            cameraCtrl = null;
            navigationCtrl = null;
            areaEffectCtrl = null;
            mediaCtrl = null;
            miniGameCtrl = null;

            uilevelMain = null;
            uilevelInput = null;
            uilevelLightDialog = null;
        }
    }
}